package com.zl.smartmall.library.im;

import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import android.app.NotificationManager;
import android.content.Context;
import android.util.SparseArray;

import com.zl.smartmall.library.im.po.MessageInfo;
import com.zl.smartmall.library.im.po.SessionInfo;
import com.zl.smartmall.library.util.CrashHandler;

/**
 *	可根据消息类型通知不同观测者更新数据
 *  @author 陈希然
 */
public class IMWorker {

	private static final String TAG = IMWorker.class.getSimpleName();
	private static Lock mLock;
	private static IMWorker mInstance;
	private Context mContext;
	private NotificationManager mNotificationManager;
	private SparseArray<MessageObservable> mObservables;//被观测者; 可能会有私信、聊天室或者消息列表等其他..

	static{
		mLock = new ReentrantLock();
	}
	
	private IMWorker(Context context) {
		// TODO Auto-generated constructor stub
		mContext = context;
		mObservables = new SparseArray<IMWorker.MessageObservable>();
		mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
	}
	
	public static IMWorker getInstance() {    	
    	return mInstance;
	}
	
	public static void init(Context context) {
		if(mInstance == null){
    		mLock.lock();
    		try{
				if(mInstance == null){
					mInstance = new IMWorker(context);
				}
    		}finally{
    			mLock.unlock();
    		}
    	}
	}
	
	/**
	 * 根据参数message的type通知对应的观测者
	 * @param message
	 */
	public void dispatchMessage(int type, MessageInfo message) {
		MessageObservable observable = mObservables.get(type);
		if(observable != null) {
			Message msg = new Message();
			msg.data = message;
			msg.type = type;
			observable.notifyDataSetChange(msg);
		}else {
			//不在聊天界面，发射一个状态栏通知
			notification(message);
			CrashHandler.d(TAG, "发射notification");
		}
	}
	
	/**
	 * 根据参数session的type通知对应的观测者
	 * @param session
	 */
	public void dispatchMessage(int type, SessionInfo session) {
		MessageObservable observable = mObservables.get(type);
		if(observable != null) {
			Message msg = new Message();
			msg.data = session;
			msg.type = type;
			observable.notifyDataSetChange(msg);
		}
	}
	
	private void notification(MessageInfo message) {
//		Intent intent = new Intent(mContext, PrivateLetter.class);
//		intent.putExtra("name", message.getSenderNickname());
//		intent.putExtra("uid", message.getSenderUid());
//		PendingIntent pending = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
////		Notification.Builder builder = new Notification.Builder(mContext);
////		builder.setTicker(message.getMessage())
////			   .setWhen(System.currentTimeMillis())
////			   .setAutoCancel(true)
////			   .setContentIntent(pending)
////			   .setContentTitle(message.getSenderNickname())
////			   .setContentText(message.getMessage())
////			   .addAction(R.drawable.app_icon, message.getMessage(), pending);
////		
////		Notification notification = builder.getNotification();
//		Notification notification = new Notification(R.drawable.ic_actionbar_logo, message.getMessage(), System.currentTimeMillis());
//		notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;
////		notification.defaults |= Notification.DEFAULT_LIGHTS; 
//		notification.ledARGB = 0x0000FF00; 
//		notification.ledOnMS = 300; 
//		notification.ledOffMS = 1000; 
//		notification.setLatestEventInfo(mContext, message.getSenderNickname(), message.getMessage(), pending);
//		mNotificationManager.notify(message.getSenderUid(), notification);

	}
	
	public void cancelNotification(int notifyId) {
		mNotificationManager.cancel(notifyId);
	}
	
	public void registerObserver(int type, Observer observer) {
		MessageObservable observable = mObservables.get(type);
		if(observable == null) {
			observable = new MessageObservable();
			mObservables.append(type, observable);
		}
		observable.addObserver(observer);
	}
	
	public void unRegisterObserver(int type, Observer observer) {
		MessageObservable observable = mObservables.get(type);
		if(observable != null) {
			observable.deleteObserver(observer);
			mObservables.delete(type);
		}
	}
	
	static class MessageObservable extends Observable {
		
		public void notifyDataSetChange(Object data) {
			setChanged();
			notifyObservers(data);
		}
	}

	static class Message {
		public int type;
		public Object data;
	}
}
